package com.five.admin.config;

import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.SimpleMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;

@Configuration
public class RabbitConfig {

    // ========================== 交换机和队列定义 ==========================
    public static final String ORDER_EVENT_EXCHANGE = "order.event.exchange";
    public static final String ORDER_CACHE_UPDATE_QUEUE = "order.cache.update.queue";
    public static final String ORDER_DLQ_EXCHANGE = "order.dlq.exchange";
    public static final String ORDER_DLQ_QUEUE = "order.dlq.queue";

    @Bean
    public FanoutExchange orderEventExchange() {
        return new FanoutExchange(ORDER_EVENT_EXCHANGE, true, false);
    }

    @Bean
    public Queue orderCacheUpdateQueue() {
        return QueueBuilder.durable(ORDER_CACHE_UPDATE_QUEUE)
                .withArgument("x-dead-letter-exchange", ORDER_DLQ_EXCHANGE)
                .withArgument("x-dead-letter-routing-key", "")
                .withArgument("x-message-ttl", 1800000)
                .build();
    }

    @Bean
    public Binding bindCacheUpdateQueue(Queue orderCacheUpdateQueue, FanoutExchange orderEventExchange) {
        return BindingBuilder.bind(orderCacheUpdateQueue).to(orderEventExchange);
    }

    @Bean
    public FanoutExchange orderDlqExchange() {
        return new FanoutExchange(ORDER_DLQ_EXCHANGE, true, false);
    }

    @Bean
    public Queue orderDlqQueue() {
        return QueueBuilder.durable(ORDER_DLQ_QUEUE).build();
    }

    @Bean
    public Binding bindDlqQueue(Queue orderDlqQueue, FanoutExchange orderDlqExchange) {
        return BindingBuilder.bind(orderDlqQueue).to(orderDlqExchange);
    }

    // ========================== 消息转换器 ==========================
    @Bean
    public SimpleMessageConverter messageConverter() {
        SimpleMessageConverter converter = new SimpleMessageConverter();
        converter.setAllowedListPatterns(
                Arrays.asList(
                        "com.five.event.OrderChangeEvent",
                        "java.lang.Long",
                        "java.lang.String",
                        "java.util.*"
                )
        );
        return converter;
    }

    // ========================== 连接工厂 ==========================
    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory factory = new CachingConnectionFactory();
        factory.setHost("47.114.117.13");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("Gxa@123456");
        factory.setVirtualHost("/");
        factory.setConnectionTimeout(5000);
        return factory;
    }

    // ========================== RabbitTemplate（含回调配置） ==========================
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        template.setMessageConverter(messageConverter());

        // 回调配置（无需重复在@PostConstruct中设置）
        template.setConfirmCallback((correlationData, ack, cause) -> {
            if (!ack) {
                System.err.println("消息未到达交换机，原因：" + cause);
            }
        });

        template.setReturnsCallback(returned -> {
            System.err.println("消息路由失败，内容：" + new String(returned.getMessage().getBody()));
        });

        return template;
    }

    // ========================== 监听器容器工厂 ==========================
    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        factory.setMessageConverter(messageConverter());
        factory.setConcurrentConsumers(2);
        factory.setMaxConcurrentConsumers(5);
        return factory;
    }

}